using ActorSystem;
using Net;
using Net.AOI;
using Net.Common;
using Net.Share;
using Net.System;

namespace AOIExample
{
#if SERVER
    public partial class Player : Actor
    {
        internal FastList<Operation> selfOpers = new();//只能发给自己 -- 只有场景线程执行
        internal Scene scene;
        internal Client client;

        public override void OnEnter(IGridObject gridObject)
        {
            var actor = gridObject as ActorBase;
            selfOpers.Add(new Operation(OperCommand.EnterArea, actor.Identity, actor.transform.Position, actor.transform.Rotation) 
            {
                actorType = actor.ActorType
            });
            if (gridObject is Robot robot)
                robot.roleCount++;
        }

        public override void OnUpdate() //服务器玩家每一帧更新
        {
            if (Grid == null)
                return;
            foreach (var gridObject in Grid) //遍历九宫格, 这里包含九宫格的所有物体
            {
                if (gridObject is ActorBase actor)
                {
                    if (actor.frame != scene.Frame) //当前帧优化， 如果已经赋值则不需要再执行
                    {
                        actor.tempOpers = actor.currOpers.GetRemoveRange(0, actor.currOpers.Count);
                        actor.frame = scene.Frame;
                    }
                    selfOpers.AddRange(actor.tempOpers); //添加到操作队
                    selfOpers.Add(new Operation(OperCommand.SyncPosition, actor.Identity, actor.transform.Position, actor.transform.Rotation));
                }
            }
            scene.SendOperitions(client, selfOpers); //只发送给在九宫格内的所有玩家， 不是全场景转发了
        }

        public override void OnExit(IGridObject gridObject)
        {
            var actor = gridObject as ActorBase;
            selfOpers.Add(new Operation(OperCommand.ExitArea, actor.Identity, actor.transform.Position, actor.transform.Rotation));
            if (gridObject is Robot robot)
                robot.roleCount--;
        }

        [OperCmd(OperCommand.SyncPosition)]
        public void SyncPosition(in Operation opt)
        {
            transform.SetPositionAndRotation(opt.position, opt.rotation);
        }
    }
#endif
}